package com.coderman.infosys.auth.infrast.gatawayimpl;

import com.coderman.infosys.auth.domain.bo.authority.AuthAggregateBO;
import com.coderman.infosys.auth.domain.bo.authority.AuthorityBO;
import com.coderman.infosys.auth.domain.bo.authority.RoleAuthAggregateBO;
import com.coderman.infosys.auth.domain.bo.authority.UserAuthAggregateBO;
import com.coderman.infosys.auth.domain.factory.AuthorityFactory;
import com.coderman.infosys.auth.domain.gataway.AuthorityQueryGataWay;
import com.coderman.infosys.auth.infrast.cache.AuthorityCache;
import com.coderman.infosys.auth.infrast.cache.RoleAuthorityCache;
import com.coderman.infosys.auth.infrast.cache.UserAuthorityCache;
import com.coderman.infosys.auth.infrast.dao.dataobject.AdminAuthorityDO;
import com.coderman.infosys.auth.infrast.dao.dataobject.AuthorityDO;
import com.coderman.infosys.auth.infrast.dao.dataobject.DataAuthorityDO;
import com.coderman.infosys.auth.infrast.dao.dataobject.SystemAuthorityDO;
import com.coderman.infosys.auth.infrast.dao.mapper.*;
import com.coderman.infosys.auth.infrast.dataconvert.AdminAuthorityConvert;
import com.coderman.infosys.auth.infrast.dataconvert.AuthorityConvert;
import com.coderman.infosys.auth.infrast.dataconvert.DataAuthorityConvert;
import com.coderman.infosys.auth.infrast.dataconvert.SystemAuthorityConvert;
import com.coderman.infosys.plat.auth.common.page.PageBO;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;

/**
 * Description:
 * date: 2022/1/9
 *
 * @author shenshuai
 * @version 1.0.0
 * @since JDK 1.8
 */
@Service
public class AuthorityQueryGataWayImpl implements AuthorityQueryGataWay {


    @Autowired
    private DataAuthorityMapper dataAuthorityMapper;

    @Autowired
    private AdminAuthorityMapper adminAuthorityMapper;

    @Autowired
    private SystemAuthorityMapper systemAuthorityMapper;


    @Autowired
    private AuthorityMapper authorityMapper;

    @Autowired
    public UserAuthorityCache userAuthorityCache;

    @Autowired
    public AuthorityFactory authorityFactory;

    @Autowired
    public AuthorityCache authorityCache;

    @Autowired
    private RoleAuthorityCache roleAuthorityCache;

    @Override
    public AuthorityBO getByAuthCode(String tenant, String authCode) {
        //这种算是通过查询的方式构建一个聚合，常规的做法会通过多个Mapper一点点构建权限聚合对象
        //那还有第二种方式，就是通过规格模式来连表查询，通常这种规格模式算是定制化的，因此需要在Mapper里面构建sql语句或者单独在QueryRepo里面存储sql语句
        //但是这种方式会让数据库底层的DO模型变得模糊，后续会通过公众号来讲述其本质原因


        //这里先通过常规的方式构建一个AuthorityBO
        AuthorityDO authorityDO = authorityMapper.getByCode(authCode);
        AuthorityBO authorityBO = AuthorityConvert.INSTANCE.do2bo(authorityDO);

        authorityBO.buildAuthTypeSet(authorityDO.getAuthorityTypeStr());

        if(authorityBO.withSystemAuth()){
            List<SystemAuthorityDO> systemAuthorityDOList = systemAuthorityMapper.getByCode(authCode);
            authorityBO.setSystemAuthorityBOList(SystemAuthorityConvert.INSTANCE.doList2boList(systemAuthorityDOList));
        }

        if(authorityBO.withDataAuth()){
            List<DataAuthorityDO> dataAuthorityDOList = dataAuthorityMapper.getByCode(authCode);
            authorityBO.setDataAuthorityBOList(DataAuthorityConvert.INSTANCE.doList2boList(dataAuthorityDOList));
        }

        if(authorityBO.withAdminSystemAuth()){
            List<AdminAuthorityDO> adminAuthorityDOList = adminAuthorityMapper.getByCode(authCode);
            authorityBO.setAdminAuthorityBOList(AdminAuthorityConvert.INSTANCE.doList2boList(adminAuthorityDOList));
        }

        return authorityBO;
    }

    @Override
    public UserAuthAggregateBO queryAuthorityWithUser(String tenant, Long userId, String systemCode) {
        Set<String> authCodeSet = userAuthorityCache.getUserAuthCodeSet(tenant, userId);
        AuthAggregateBO authorityBO = new AuthAggregateBO();
        authCodeSet.forEach(authCode->{
            authorityBO.putSystem(authorityCache.getAuthSystem(tenant,authCode));
            authorityBO.putAddress(authorityCache.getAuthAddress(tenant,authCode));
            authorityBO.putColumn(authorityCache.getAuthDatacolumn(tenant,authCode));
            authorityBO.putDepart(authorityCache.getAuthDepartment(tenant,authCode));
            authorityBO.putJob(authorityCache.getAuthJobs(tenant,authCode));
        });
        UserAuthAggregateBO userAuthAggregateBO = new UserAuthAggregateBO();
        userAuthAggregateBO.setAuthAggregateBO(authorityBO);
        userAuthAggregateBO.setUserId(userId);
        return userAuthAggregateBO;
    }

    @Override
    public RoleAuthAggregateBO queryAuthorityWithRole(String tenant, String roleCode) {
        Set<String> authCodeSet = roleAuthorityCache.getRoleAuthCodeSet(tenant, roleCode);
        AuthAggregateBO authorityBO = new AuthAggregateBO();
        authCodeSet.forEach(authCode->{
            authorityBO.putSystem(authorityCache.getAuthSystem(tenant,authCode));
            authorityBO.putAddress(authorityCache.getAuthAddress(tenant,authCode));
            authorityBO.putColumn(authorityCache.getAuthDatacolumn(tenant,authCode));
            authorityBO.putDepart(authorityCache.getAuthDepartment(tenant,authCode));
            authorityBO.putJob(authorityCache.getAuthJobs(tenant,authCode));
        });
        RoleAuthAggregateBO roleAuthAggregateBO = new RoleAuthAggregateBO();
        roleAuthAggregateBO.setRoleCode(roleCode);
        roleAuthAggregateBO.setAuthAggregateBO(authorityBO);
        roleAuthAggregateBO.setUserIdList(Lists.newArrayList());
        return roleAuthAggregateBO;
    }

    @Override
    public List<AuthorityBO> getPageList(PageBO pageBO) {
        List<AuthorityDO> authorityBOList = authorityMapper.getPageList(pageBO);
        return AuthorityConvert.INSTANCE.doList2boList(authorityBOList);
    }

}
